from mesh_node import *

class parse_mesh_text():
	"""
	Parses the mtrees files of mesh
	"""
	def __init__(self, mesh_filename):
		self.mesh_filename = mesh_filename
		self.file = open(self.mesh_filename, 'r')
		self.entries = {}
		self.current_line = 0
		self.current_record = 0
		self.current_record_pos = 0
		
	def create_table(self):
		"""
		Creates a hash table of all the mesh entries in the file
		"""
		file = self.file
		while(True):
			line = file.readline()
			if not line:
				break
			line = line[:-2] #remove the newline
			(name, id) = line.split(';')
			#print 'name =',name, 'id =',id
			if(len(id.split('.')) > 1):
				parent = '.'.join(id.split('.')[:-1])
			else:
				parent = None
			this_node = mesh_node(id, name)
			self.entries[id] = this_node #add to the list
			if(parent):
				parent_node = self.entries[parent]
				parent_node.add_child(this_node)
				this_node.set_parent(parent_node)
		file.close()
		
	def invert_dict(self):
		"""
		Takes the entries with id as the key and returns a new dict with names as the key
		Returns a special dictionary whose value for any key is a list
		"""
		invert = mdict()
		for (id, node) in self.entries.items():
			invert[node.name] = node
			
		return invert
		
	def dump_table(self, dumpfilename):
		"""
		Puts all the entries in a text file
		"""
		file = open(dumpfilename, 'w')
		for (id, node) in self.entries.items():
			file.write(id + '\n')
			file.write(node.name + '\n')
			if(node.parent):
				file.write(node.parent.id + '\n')
			else:
				file.write('-1\n')
			file.write(str(node.des_pos) + '\n\n')
			
		file.close()
		
	def put_linenos(self, desfilename):
		"""
		Puts the appropriate line numbers in the entries based on the description file
		"""
		file = open(desfilename, 'r')
		nulls = 0
		old_percent = 0
		percent = 0
		while(True):
			try:
				records = self.get_next_record(file)
				if records == None:
					break
				if len(records) == 0:
					continue
				for record in records:
					(id, pos, line) = record
					self.entries[id].des_pos = pos
					percent = int((line*100)/854845)
					if(percent > old_percent + 10):
						print percent, '%'
						old_percent = percent
					#print 'pos of', self.entries[id].id, 'is ', pos
			except:
				break
				
		file.close()
			
	def get_next_record(self, file):
		"""
		Returns a single record from the description file
		"""
		records = []
		while(True):
			line = file.readline()
			if not line:
				return None
			line = line[:-1]
			if not line:
				self.current_line = self.current_line + 1
				self.current_record = self.current_line
				self.current_record_pos = file.tell()
				return records
			elif line[0] == '*':
				self.current_line = self.current_line + 1
				continue
			#print line
			elif line[:3] == 'MN ':
				entries = line.split('=')
				value = entries[1].strip()
				records.append((value, self.current_record_pos, self.current_record))
			self.current_line = self.current_line + 1
						
if __name__ == '__main__':
	parse = parse_mesh_text("MESH/ascii/mtrees2007.bin")
	parse.create_table()
	#table = parse.entries
	#sample = table['B04.909.777.455.600.670.600.750.700']
	#sample_parent = sample.parent
	#print 'parent of B04.909.777.455.600.670.600.750.700 is', sample_parent.name, sample_parent.id
	#inverse = parse.invert_dict()
	#mam = inverse['Mammary Glands, Human']
	#parent = mam[0].parent
	#print 'parent of (Mammary Glands, Human) is', sample_parent.name, sample_parent.id
	#print table
	#print 'all ancestors of', sample.id
	#for a in sample.get_ancestors():
	#	print a.id, a.name
	parse.put_linenos('MESH/ascii/d2007.bin')
	parse.dump_table('dump')
	#parse.put_linenos('des')
	#parse.dump_table('dump')